package com.example.k8s.hello.boot.oss.utils;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Base64;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class ImgUtil {
    /**
     * BufferedImage 编码转换为 base64
     * @param bufferedImage
     * @return
     */
    public static String bufferedImageToBase64(BufferedImage bufferedImage) {
        try(ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            ImageIO.write(bufferedImage, "png", out);//写入流中

            byte[] bytes = out.toByteArray();//转换成字节
            Base64.Encoder encoder = Base64.getEncoder();
            String png_base64 = encoder.encodeToString(bytes).trim();//转换成base64串

            return "data:image/jpg;base64," + png_base64;
        } catch (IOException e) {
            throw new RuntimeException("BufferedImage 编码转换为 base64出错", e);
        }
    }

    /**
     * base64 编码转换为 ByteArrayOutputStream
     * @param base64
     * @return
     */
    public static ByteArrayOutputStream base64ToOutputStream(String base64) {
        BufferedImage bufferedImage = base64ToBufferedImage(base64);

        return ImgUtil.bufferedImageToOutputStream(bufferedImage);
    }

    /**
     * base64 编码转换为 BufferedImage
     * @param base64
     * @return
     */
    public static BufferedImage base64ToBufferedImage(String base64) {
        Base64.Decoder decoder = Base64.getDecoder();

        String newBase64 = regexBase64(base64);

        byte[] bytes = null;
        try {
            bytes = decoder.decode(newBase64.trim());
        } catch (IllegalArgumentException e) {
            throw new RuntimeException("base64编码不正确", e);
        }

        try (ByteArrayInputStream in = new ByteArrayInputStream(bytes)) {
            return ImageIO.read(in);
        } catch (IOException e) {
            throw new RuntimeException("base64 编码转换为 BufferedImage出错", e);
        }
    }

    /**
     * 正则去除base64多余的前缀，如data:image/jpeg;base64,
     * @param base64
     * @return
     */
    private static String regexBase64(String base64) {
        // 正则匹配 Base64 前缀
        String regex = "^data:(.+?);base64,";
        Matcher matcher = Pattern.compile(regex).matcher(base64);

        if (matcher.find()) {
            // 移除匹配的前缀
            return base64.substring(matcher.end());
        }
        return base64;
    }

    /**
     * BufferedImage 编码转换为 ByteArrayOutputStream
     * @param bufferedImage
     * @return
     */
    public static ByteArrayOutputStream bufferedImageToOutputStream(BufferedImage bufferedImage) {
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()){
            ImageIO.write(bufferedImage, "png", out);

            return out;
        } catch (IOException e) {
            throw new RuntimeException("BufferedImage 编码转换为 ByteArrayOutputStream出错", e);
        }
    }

    /**
     * 图片压缩
     * @param in
     * @param out
     * @param format
     * @param targetWidth
     * @param targetHeight
     */
    public static void resizeImage(InputStream in, OutputStream out, String format, int targetWidth, int targetHeight) {
        try {
            // 读取输入文件到 BufferedImage
            BufferedImage inputImage = ImageIO.read(in);

            // 创建目标大小的 BufferedImage
            BufferedImage outputImage = new BufferedImage(targetWidth, targetHeight, inputImage.getType());

            // 通过 Graphics2D 对图片进行缩放
            Graphics2D g2d = outputImage.createGraphics();
            g2d.drawImage(inputImage.getScaledInstance(targetWidth, targetHeight, Image.SCALE_SMOOTH), 0, 0, null);
            g2d.dispose(); // 释放资源

            // 将压缩后的图片写入输出文件
            ImageIO.write(outputImage, format, out);  // 可以根据需要改为 png、jpeg 等格式
        } catch (IOException e) {
            throw new RuntimeException("图片压缩出错", e);
        }
    }

    /**
     * 增加水印
     * @param text
     * @param in
     * @param out
     * @param format
     */
    public static void addTextWatermark(InputStream in, OutputStream out, String format){
        try {
            // 读取输入文件到 BufferedImage
            BufferedImage image = ImageIO.read(in);

            // 创建 Graphics2D 对象
            Graphics2D g2d = (Graphics2D) image.getGraphics();

            // 启用抗锯齿功能，提高文本质量
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);

            // 设置水印透明度
            AlphaComposite alpha = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f);
            g2d.setComposite(alpha);

            // 设置水印颜色、字体和大小
            g2d.setColor(Color.GRAY);
            g2d.setFont(new Font("Microsoft YaHei", Font.BOLD, 40));

            // 定位水印的位置
            int x = image.getWidth() / 5;
            int y = image.getHeight() / 2;

            // 绘制水印文本
            g2d.drawString("中科超清", x, y);

            // 释放资源
            g2d.dispose();

            // 将带有水印的图片写入输出文件
            ImageIO.write(image, format, out);
        } catch (IOException e) {
            throw new RuntimeException("增加水印出错", e);
        }
    }

    public static void main(String[] args) throws FileNotFoundException {
        FileInputStream fileInputStream = new FileInputStream("C:\\Users\\Administrator\\Pictures\\86abb0fc3b7877cadaaa102267cf578.png");
        FileOutputStream fileOutputStream = new FileOutputStream("C:\\Users\\Administrator\\Pictures\\out.png");
//        resizeImage(fileInputStream, fileOutputStream, "png", 400, 200);
        addTextWatermark(fileInputStream, fileOutputStream, "png");
    }
}
